parser grammar CParser;

options {
  language = Java;
  tokenVocab = CLexer;
}

@header {
package PL.prac8;
}

@rulecatch {catch (RecognitionException rre) {
  throw rre;}
 }

@members {int nivelcuerpo = 0;}


entrada: funcion EOF;


//Definición de una variable **TIPO (ASTERISCO)? IDENT (ACORCHETE CCORCHETE)?**:
variable returns [String salida = ""]: a=TIPO{salida = a.getText();} (b=ASTERISCO {salida = salida + b.getText();})? 
                                       c=IDENT {salida = salida + " "+ c.getText();} (ACORCHETE CCORCHETE {salida = salida + "[]";})?
                                       {salida = salida + " ";};

//Partes de una funcion: cabecera y body. 
//**cabecera body**
funcion returns [String salida = ""]: a=cabecera b=body { salida = a+b; System.out.print(salida);};

//**(VOID|TIPO) (IDENT|MAIN) APARENTESIS llamada_variable CPARENTESIS**
cabecera returns [String salida = ""]: a=(VOID|TIPO) {salida = a.getText() + " ";} b=(IDENT|MAIN) {salida = salida + b.getText()+ " ";}
                                  APARENTESIS c=llamada_variable CPARENTESIS {salida = salida + "("+c + ") ";};

//**(VOID| variable (COMA variable)* **                             
llamada_variable returns [String salida = ""]: (VOID {salida = "void";}| (a=variable {salida = a;}
                                               (COMA b=variable{salida = salida + ", "+b;})*));

//ALLAVE cuerpo* CLLAVE
body returns [String salida = ""]: ALLAVE {salida = "{ \n";} (c=cuerpo {salida = salida + c;})* CLLAVE {salida = salida+ "\n}";};


// Parte que está entre llaves.
//**(sentencia|asignacion|definicion|llamada_funcion| BREAK SEPARADOR)**
cuerpo returns [String salida = ""]: ( a=sentencia {salida = a;}
                                    | b=asignacion {salida = b;}
                                    | c=definicion {salida = c;}
                                    |d =llamada_funcion {salida = d;}
                                    |BREAK SEPARADOR {salida = "break; \n";});



//**(bucle|condicion|buclefor) cuerposentencia**
sentencia returns [String salida = ""]: (a = bucle {salida= a;}|b= condicion{salida = b;}|c = buclefor{salida = c;}) b=cuerposentencia {salida = salida + b;};

//**WHILE comparacion**
bucle returns [String salida = ""]: WHILE{salida = "while ";} a =comparacion {salida = salida + a;};

                                    
//**APARENTESIS relglas ((AND|OR) reglas)* CPARENTESIS
comparacion returns [String salida = ""]: APARENTESIS a= reglas {salida = "( " + a ;}
                                          ((AND {salida = salida + " && ";} | OR {salida = salida + " || ";}) 
                                          b=reglas {salida = salida + b;})* CPARENTESIS {salida = salida +" )";};


//**(subregla COMPARADORES subregla) | (NOT? IDENT) |cond_aritmetico**
reglas returns [String salida = ""]: (a=subregla b=COMPARADORES c=subregla {salida = a+ " " + b.getText() + " " + c;}) 
                                     | ((d=NOT {salida = "!";})? e=IDENT {salida = salida + e.getText();}) 
                                     |f = cond_aritmetico{salida = f;};
                                     
//**(IDENT| NUMERO|operacion)**
subregla returns [String salida = ""]: (a= IDENT {salida = a.getText();}
                                      | a=NUMERO {salida = a.getText();}
                                      |b=operacion {salida = b;});
                                      
//** IDENT COMPARADORES NUMERO INTERROGANTE NUMERO DOSPUNTOS NUMERO**
cond_aritmetico returns [String salida = ""]: a=IDENT b=COMPARADORES c=NUMERO INTERROGANTE d=NUMERO DOSPUNTOS e=NUMERO 
                                {salida = a.getText()+ " " + b.getText() + " "+ c.getText()+ "?" + " " + d.getText()+ ": "+ e.getText();};

//**(ALLAVE cuerpo+ CLLAVE |cuerpo)**
cuerposentencia returns [String salida = ""]: (ALLAVE (b=cuerpo)+ CLLAVE {salida = "{ \n"+ b + "}";} |c=cuerpo {salida = c;});
                                          
//**(IDENT|NUMERO) ((MAS|MENOS|ASTERISCO|BARRA) (IDENT|NUMERO))**
operacion returns [String salida = ""]: a=(IDENT|NUMERO){salida = a.getText();} 
                                      (b=(MAS|MENOS|ASTERISCO|BARRA) {salida = salida + " "+ b.getText();} 
                                      c=(IDENT|NUMERO) {salida = salida + " "+ c.getText();});
//**IF comparacion**
condicion returns [String salida = ""]: IF a=comparacion {salida = "if " + a;};
//**FOR comparacion_for**
buclefor returns [String salida = ""]: FOR a=comparacion_for {salida = "for " + a;};
//**APARENTESIS comparacion1? SEPARADOR comparacion2? SEPARADOR comparacion3? CPARENTESIS**
comparacion_for returns [String salida = ""]: APARENTESIS {salida = "( ";} 
                                             (b=comparacion1{salida = salida + b;})? SEPARADOR {salida = salida + "; \n";}
                                              (c=comparacion2{salida = salida + c;})? SEPARADOR {salida = salida + "; \n";}
                                              (d=comparacion3 {salida = salida + d;})? CPARENTESIS {salida = salida + "; \n";};
//**(TIPO)? IDENT IGUAL NUMERO**
comparacion1 returns [String salida = ""]: (a=TIPO {salida = a.getText()+ " ";})? g=IDENT{salida = salida + g.getText() + " ";} 
                                           IGUAL {salida = salida + "= ";} c=NUMERO {salida = salida + c.getText();};
//**IDENT COMPARADORES (NUMERO|IDENT)**
comparacion2 returns [String salida = ""]: a=IDENT b= COMPARADORES c=(NUMERO|IDENT) 
                                          {salida = a.getText()+ " " + b.getText()+ " " + c.getText();};
//**IDENT ( MAS MAS | MENOS MENOS) **
comparacion3 returns [String salida = ""]: a=IDENT {salida = a.getText();}
                                          (MAS MAS{salida = salida + "++";}| MENOS MENOS{salida = salida + "--";});
//**IDENT IGUAL (IDENT|NUMERO|CADENA|CARACTER) ((MAS|MENOS|ASTERISCO|BARRA) (IDENT|NUMERO|CADENA|CARACTER))* SEPARADOR;**
asignacion returns [String salida = ""]: a=IDENT IGUAL c=(IDENT|NUMERO|CADENA|CARACTER) {salida = a.getText() + " = "+c.getText();}
                                        (d=(MAS|MENOS|ASTERISCO|BARRA) e=(IDENT|NUMERO|CADENA|CARACTER)
                                        {salida = salida + " " + d.getText() + " " + e.getText();})* SEPARADOR{salida = salida + "; \n";};
//**TIPO IDENT (COMA IDENT) SEPARADOR**
definicion returns [String salida = ""]: a=TIPO b=IDENT {salida = a.getText() + " " + b.getText();}
                                        (COMA c=IDENT{salida = salida + ", "+c.getText();})* SEPARADOR{salida = salida + "; \n";};
//**IDENT APARENTESIS tipos (COMA tipos)* CPARENTESIS SEPARADOR;**
llamada_funcion returns [String salida = ""]: a=IDENT APARENTESIS {salida = a.getText() + "( ";}
                       b=tipos {salida = salida + b;} (COMA c=tipos {salida = salida + ", "+ c;})* 
                       CPARENTESIS SEPARADOR {salida = salida + " );";};
identificador returns [String salida = ""]: a=IDENT {salida = a.getText();}
                                           (ACORCHETE b=NUMERO CCORCHETE {salida = salida + "[" + b.getText() + "]";})?;
tipos returns [String salida = ""]: a=identificador {salida = a;}
                                    | b= NUMERO {salida = b.getText();}
                                    | c=CADENA {salida = c.getText();}
                                    |d=CARACTER {salida = d.getText();};
